Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XPC service for Lion Sandboxing #165

Closed
wants to merge 1 commit into from

Conversation

wbyoung
Copy link

@wbyoung wbyoung commented Mar 20, 2012

This fixes #163. It requires that you copy the XPC service into your main application bundle in Contents/XPCServices and runs the remove from quarantine step of copying the finish_installation app as well as launching finish_installation app outside of the sandbox. Sparkle will function exactly as it does now for applications that do not copy the XPC service into their application bundle.

This fixes sparkle-project#163. It requires that you copy the XPC service into your main application bundle in
Contents/XPCServices and runs the remove from quarantine step of copying the finish_installation
app as well as launching finish_installation app outside of the sandbox. Sparkle will function
exactly as it does now for applications that do not copy the XPC service into their application
bundle.
@andymatuschak
Copy link
Contributor

Very exciting! I'll try to make time this week to review and integrate.
On Mar 20, 2012, at 8:04 AM, Whitney Young reply@reply.github.com wrote:

This fixes #163. It requires that you copy the XPC service into your main application bundle in Contents/XPCServices and runs the remove from quarantine step of copying the finish_installation app as well as launching finish_installation app outside of the sandbox. Sparkle will function exactly as it does now for applications that do not copy the XPC service into their application bundle.

You can merge this Pull Request by running:

git pull https://github.com/wbyoung/Sparkle master

Or you can view, comment on it, or merge it online at:

#165

-- Commit Summary --

  • Added an XPC service to deal with sandboxing.

-- File Changes --

A Configurations/ConfigService.xcconfig (5)
A Configurations/ConfigServiceDebug.xcconfig (5)
A Configurations/ConfigServiceRelease.xcconfig (3)
M SUBasicUpdateDriver.m (18)
M SUPlainInstallerInternals.m (5)
A SUXPC.h (16)
A SUXPC.m (72)
A SandboxService.plist (29)
M Sparkle.xcodeproj/project.pbxproj (165)
M finish_installation.m (1)
A sandbox_service.m (91)

-- Patch Links --

https://github.com/andymatuschak/Sparkle/pull/165.patch
https://github.com/andymatuschak/Sparkle/pull/165.diff


Reply to this email directly or view it on GitHub:
#165

@andymatuschak
Copy link
Contributor

Thanks very much for the patch. I have made only a first pass at review, as I am seriously writing this from a beach on Maui.

I don't think that the launch_task command of the service can be permitted to be so general. An exploit in the host app could use this to execute an arbitrary task outside the sandbox—no good! I think this could be remedied by expressing the path to finish_installation in relative terms from the service. We'd also need to ensure something like the path being installed and the path being updated are signed with the same code signing identity as the parent app.

I'm also concerned about the usage of synchronous XPC messages. We can't block the main thread of the client app in that way.

While I don't presently have time to handle these issues myself, I would be happy to assist you in doing so if needed. Thanks again for taking the time to do this.

@wbyoung
Copy link
Author

wbyoung commented Apr 4, 2012

I'll try to work on some of these pieces when I get time. I've been pretty busy recently, though. Any help would be appreciated!

Some thoughts:

How should the launch_task command be specified relatively? Should there be just a single argument passed to the service that is the name of the finish_installation app (since it could be renamed) and allow the launch_task to figure out the path to the application support folder? I think this should mostly work, but are there cases where you can customize things that might change which bundle is used for calculating the application support folder name (or anything like that)?

The code signing part makes sense as well, but is there a good way to extract information about who signed a binary? All I know is codesign, but that won't work. Is there an API for this?

In testing the synchronous XPC messages weren't really a problem. I guess there's a possibility of a hang, but there's also file IO going on in the same method which could hang as well. I can't test right now, but is this method running on the main thread anyway?

@andymatuschak
Copy link
Contributor

On Apr 3, 2012, at 8:33 PM, Whitney Young reply@reply.github.com wrote:

I'll try to work on some of these pieces when I get time. I've been pretty busy recently, though. Any help would be appreciated!

Some thoughts:

How should the launch_task command be specified relatively? Should there be just a single argument passed to the service that is the name of the finish_installation app (since it could be renamed) and allow the launch_task to figure out the path to the application support folder? I think this should mostly work, but are there cases where you can customize things that might change which bundle is used for calculating the application support folder name (or anything like that)?

I think all this means we need to ensure that the client application copies finish_application into a path which can be computed by trusted information.

Also: finish_installation's binary should match a compile-time checksum (the client app is not trusted!). I suppose that if we have this part, we don't necessarily need the fixed-path part.

The code signing part makes sense as well, but is there a good way to extract information about who signed a binary? All I know is codesign, but that won't work. Is there an API for this?

Yep! https://developer.apple.com/library/mac/#documentation/Security/Reference/CodeSigningRef/Reference/reference.html

In testing the synchronous XPC messages weren't really a problem. I guess there's a possibility of a hang, but there's also file IO going on in the same method which could hang as well. I can't test right now, but is this method running on the main thread anyway?

The relevant method is indeed running on the main thread. I guess the more significant point is that the _sync variants of the XPC APIs are effectively deprecated and are intended only for migratory (i.e. from MIG) applications.

@wbyoung
Copy link
Author

wbyoung commented Apr 5, 2012

Seems good. I'll take a look when I get a chance.

It seems the better way to go would be to verify that the finish_installation binary is code-signed with the same key as the client application. This will provide better security than using a checksum (which would still allow someone to pad an executable to match the hash). At that point, the path tot the executable doesn't really matter, would you agree? I'll take a look at the API and try to get that together.

I didn't know that the _sync variants were deprecated. Thanks for letting me know. I'll refactor and get that fixed for sure.

@fraserhess
Copy link

Hello,
I've been looking over this code with the hope that it could help bail me out of a difficult decision (whether or not to go App Store-only) and I have a couple of comments:

  • I think Andy is right regarding the synchronous XPC calls. The documentation is very clear.
  • I'm not sure I agree about needing to authenticate the caller of the XPC service. While it's not the best, the rest of app is running in a sandbox and that's a significant security improvement over the non-sandbox alternative.
  • In general, Whitney's solution is a valiant effort to solve a difficult problem, with surprisingly little code. The problem occurs when trying to graft an asynchronous API (XPC) into places where Sparkle uses synchronous APIs.
  • There are no xpc_release() calls and therefore, memory leaks are occurring.
  • I'm thinking the solution probably involves another branch of Sparkle, where in the parts that need to be reworked for asynchronous calls are substantially different as opposed to more conditionals all over the place. And yes, that would have to be Lion only.

@wbyoung
Copy link
Author

wbyoung commented May 30, 2012

Fraser,

Good points. Since the only XPC calls are in a function returning void, there wouldn't be that much more work to make it async. I don't think another branch would be necessary.

@samdeane
Copy link
Contributor

samdeane commented Jul 4, 2012

Did this work get any further? Happy to try to help, but it would be handy to know that I'm not duplicating effort.

@samdeane
Copy link
Contributor

samdeane commented Jul 4, 2012

Looking at the code, it seems like installWithToolAndRelaunch should be easy enough to split into two, with the completion of the copying triggering the second part.

However, there are two issues.

First, the existing file copying code is effectively synchronous, so I'm not convinced that there's an absolute requirement to make the xpc one async. I guess that this is a good thing...

Second, the last thing that the routine does is to terminate the app. If this happens before the launch task has completed, there might be an issue with the xpc service - are we sure that it will survive the app that launched it going away?

Perhaps more to the point, if we make either of the xpc calls asynchronous, that means that the original installWithToolAndRelaunch needs to return without having called NSApp terminate. This presumably has the potential to change the behaviour of whatever called it, which might lead to all sorts of mess.

Anyone got any comments? Are my concerns relevant - bearing in mind that I don't know this code base at all!

@wbyoung
Copy link
Author

wbyoung commented Jul 5, 2012

Sam,

I think you'd want to terminate after the XPC service completed. I believe that'd be possible, but this was the first time that I worked with XPC, so I don't know for sure.

Other than that I think Andy would know better because he'd be more familiar with the code base.

I probably won't be finishing the work on this now, though. We just recently decided that the App we were using this for with sandboxing will be only sold through the Mac App Store now.

@samdeane
Copy link
Contributor

samdeane commented Jul 5, 2012

Thanks Whitney. I think you're right, the main code should wait until the XPC service completes.

This means that installWithToolAndRelaunch would return before the launching had completed. Hopefully that won't cause problems, but maybe Andy can say.

@andymatuschak
Copy link
Contributor

w.r.t. the security-in-XPC-service issue, I expect that the new bits in https://github.com/andymatuschak/Sparkle/tree/CodeSigning should help a great deal!

@andymatuschak
Copy link
Contributor

It's true that making the XPC calls asynchronous will change the code flow somewhat, but I don't think that will be particularly troublesome to any of the callers.

@lwdupont
Copy link

lwdupont commented Jul 9, 2012

Can I help out on getting this working and secure? I've got some time available in the next few weeks.

@samdeane
Copy link
Contributor

@lwdupont go for it - I was planning on having a look at it next week, but I won't have time before then, and something else will probably come up to distract me!

@lwdupont
Copy link

@samdeane Ok, thanks. I'll probably give it a start tomorrow morning.

@erikaderstedt
Copy link

I changed wbyoung's patch to make the XPC calls asynchronous (commit here). A few issues remain:

  • The host app still needs entitlements for full network access. If I want to use the same entitlements file for the App Store and non-App Store versions of my app (and I do), this seems overly excessive. This means I need to put all the URL downloading code in an XPC service as well.
  • The launch_task command is still quite general. I don't know if this is a big problem or not.

@erikaderstedt
Copy link

Ok, so now I put the networking code in an XPC as well. This means that Sparkle will not require any extra entitlements; the Sparkle Test App runs without any entitlements at all. You can find the branch here. I've also made a few config changes to get Sparkle to build in Xcode 4.4 on 10.7; my git-fu is too weak to split this up after the fact, sorry.

So, how does it work?

  • I added a new service com.andymatuschak.Sparkle.download-service. This builds on the SandboxedFetch sample from Apple.
  • I added a class SUXPCURLDownload, that emulates NSURLDownload and calls the same delegate methods.
  • The SUXPCURLDownload class talks to a new XPC that internally uses libcurl.

Limitations:

  • Remote release note URLs are not supported.
  • https:// is not supported because libcurl doesn't do this out-of-the-box. Can probably be added if required. Now we all sign apps with Developer-ID anyway, right?
  • Not tested in any case other than the default Sparkle Test App case.

@samdeane
Copy link
Contributor

Hi Erik, I'm going to give this a go for a new beta build of Ambientweet. Anything I should watch out for?

@samdeane
Copy link
Contributor

Just tested this in the wild.

Running a debug build under Xcode worked fine - it successfully downloaded and installed.

However, running a release build outside of Xcode resulted in this:

Process: Ambientweet FastSpring [57842]
Path: /Users/USER/*/Ambientweet.app/Contents/MacOS/Ambientweet FastSpring
Identifier: Ambientweet FastSpring
Version: 1.1.2b1 (107)
Code Type: X86-64 (Native)
Parent Process: Ambientweet FastSpring [57828]
User ID: 502

Date/Time: 2012-08-22 18:19:30.615 +0100
OS Version: Mac OS X 10.8 (12A269)
Report Version: 10

Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000

Application Specific Information:
*** NSTask: Task create for path '/Volumes/titan/Users/sam/Library/Containers/com.elegantchaos.ambientweet/Data/Library/Application Support/Ambientweet/finish_installation.app/Contents/MacOS/finish_installation' failed: 22, "Invalid argument". Terminating temporary process.
Performing @selector(installAndRestart:) from sender NSButton 0x1002d4d90
*** multi-threaded process forked ***

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 com.apple.Foundation 0x00007fff8cd3e488 NEW_PROCESS_COULD_NOT_BE_EXECD + 5
1 com.apple.Foundation 0x00007fff8cc17b41 -[NSConcreteTask launchWithDictionary:] + 3544
2 com.apple.Foundation 0x00007fff8cc1661d +[NSTask launchedTaskWithLaunchPath:arguments:] + 205
3 org.andymatuschak.Sparkle 0x0000000100097345 0x100089000 + 58181
4 org.andymatuschak.Sparkle 0x0000000100096d1e 0x100089000 + 56606
5 org.andymatuschak.Sparkle 0x000000010009886b 0x100089000 + 63595
6 com.apple.AppKit 0x00007fff88831219 -[NSApplication sendAction:to:from:] + 342
7 com.apple.AppKit 0x00007fff88831077 -[NSControl sendAction:to:] + 85
8 com.apple.AppKit 0x00007fff88830fab -[NSCell _sendActionFrom:] + 138
9 com.apple.AppKit 0x00007fff8882f493 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 1855
10 com.apple.AppKit 0x00007fff8882ece1 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 504
11 com.apple.AppKit 0x00007fff8882e45c -[NSControl mouseDown:] + 820
12 com.apple.AppKit 0x00007fff88825dce -[NSWindow sendEvent:] + 6853
13 com.apple.AppKit 0x00007fff88821f04 -[NSApplication sendEvent:] + 5761
14 com.apple.AppKit 0x00007fff88737c7a -[NSApplication run] + 636
15 com.apple.AppKit 0x00007fff886dc656 NSApplicationMain + 869
16 com.elegantchaos.ambientweet 0x0000000100001d04 start + 52

@erikaderstedt
Copy link

Do you see any sandbox violations in Console?

@samdeane
Copy link
Contributor

Ah, I'm an idiot :)

I didn't add the XPC services to my application...

@samdeane
Copy link
Contributor

It appears to be working now.

If you download http://downloads.elegantchaos.com/ambientweet/ambientweet-v1.1.2b2.zip, it should try to update to 1.1.2b3. Seems to work for me, but it would be good to hear if it's broken for others :)

@samdeane
Copy link
Contributor

My version of @erikaderstedt's branch is samdeane/Sparkle branch:xpc-service (here)

It's pretty much identical at this point.

@rudyrichter
Copy link
Contributor

prodding andy to evaluate the submitted patch/pull request to see if it meets his approval for inclusion in master

@andymatuschak
Copy link
Contributor

Erik, thanks so much for your work here! I've reviewed your branch, and aside from cosmetic issues, I have a few questions and a few concerns:

  • install_service is still insecure to the extent that it defeats the purpose of the parent app being in the sandbox in the first place: it's a privileged service which will copy an arbitrary file to an arbitrary place. That's not okay!
    • Since this is the privileged process, it must be the entity which verifies the integrity of the update, not the host (as is done now).
    • This service should ensure that the update satisfies the host's designated requirement. Check out the CodeSigning branch's SUCodeSigningVerifier.
    • Since the parent app has read/write access to the update path, the install service must defend against symlink attacks which would allow an exploited parent app to swap a malicious update in immediately after the service verifies the code signature.
    • This can be accomplished by chdir()ing to the update path before performing the check, then using only relative paths to access anything in the update's path henceforth.
  • Why does the downloading service use libcurl, not NSURLDownload?
  • I like very much that you tried to make it so that the parent application doesn't have to have a network access entitlement, but I'm concerned that in general, the download service won't be sufficient for release notes: many of them have images, JavaScript, etc.
    • I guess we could document that if you're going to use "rich" release notes, your app must support full network access? Seems kind of lame, but maybe it's better than nothing.
  • Why do you pass the file descriptor of the downloaded file from the downloading service back to the host? It doesn't seem to do anything with it.
  • Why make another XPC connection to send progress reports on from the downloading service, rather than simply sending messages over the connection already established from the host?
  • I think we should prohibit the installation service from accessing the network via sandbox_init and probably prohibit the downloading service from accessing anything but /tmp via same.

I may have time this or next weekend to try to help finish this off, if that'd be useful. Thanks again for your contributions here!

@erikaderstedt
Copy link

Hi!

Thanks for taking the time to review the branch! To answer your questions:

My main motivation for supporting Sparkle in a sandboxed app isn't security; I just want to maintain two versions of my app; one on the App Store and one outside. Preferably, they should be as similar as possible, and that includes sandboxing. That said, it is certainly possible to move the integrity check to the XPC service. I'd love to do it, but it would have to wait until after the next version of my app is launched in a few months (hopefully).

libcurl vs. NSURLDownload - good question. The SandboxedFetch sample from Apple uses libcurl, and that's what I used as a starting point. The main function call that actually fetches the file, curl_easy_perform, is synchronous, which is the main difference between libcurl and NSURLDownload. Not very difficult to work around, I guess.

If a lot of people are using "rich" release notes (with Javascript, for example), it would be possible to make a WebDataSource that uses the download_service XPC. This feels like it would take a lot of work. One alternative would be to open these release notes in the user's default browser using NSWorkspace.

You're right, the file descriptor is not needed. This is "cruft" left over from SandboxedFetch, where the download was made to a temporary file created and named by the XPC service. Since we're now passing the destination file path instead, this is superfluous.

I really, really, tried to use the same XPC connection for progress updates, but wasn't able to get it to work. Finally I gave up and did it the same way SandboxedFetch does it. I still don't understand why it does it this way.

Limiting the XPC services using sandboxing seems like a good idea!

Cheers,
Erik Aderstedt

5 sep 2012 kl. 07:47 skrev Andy Matuschak:

Erik, thanks so much for your work here! I've reviewed your branch, and aside from cosmetic issues, I have a few questions and a few concerns:

install_service is still insecure to the extent that it defeats the purpose of the parent app being in the sandbox in the first place: it's a privileged service which will copy an arbitrary file to an arbitrary place. That's not okay!
Since this is the privileged process, it must be the entity which verifies the integrity of the update, not the host (as is done now).
This service should ensure that the update satisfies the host's designated requirement. Check out the CodeSigning branch's SUCodeSigningVerifier.
Since the parent app has read/write access to the update path, the install service must defend against symlink attacks which would allow an exploited parent app to swap a malicious update in immediately after the service verifies the code signature.
This can be accomplished by chdir()ing to the update path before performing the check, then using only relative paths to access anything in the update's path henceforth.
Why does the downloading service use libcurl, not NSURLDownload?
I like very much that you tried to make it so that the parent application doesn't have to have a network access entitlement, but I'm concerned that in general, the download service won't be sufficient for release notes: many of them have images, JavaScript, etc.
I guess we could document that if you're going to use "rich" release notes, your app must support full network access? Seems kind of lame, but maybe it's better than nothing.
Why do you pass the file descriptor of the downloaded file from the downloading service back to the host? It doesn't seem to do anything with it.
Why make another XPC connection to send progress reports on from the downloading service, rather than simply sending messages over the connection already established from the host?
I think we should prohibit the installation service from accessing the network via sandbox_init and probably prohibit the downloading service from accessing anything but /tmp via same.
I may have time this or next weekend to try to help finish this off, if that'd be useful. Thanks again for your contributions here!


Reply to this email directly or view it on GitHub.

@andymatuschak
Copy link
Contributor

Thanks for the answers, Erik. I understand now why you weren't too concerned about the security ramifications—that makes sense. I'm thinking about it more for apps which never ship on the App Store, but which are still sandboxed; they should still be secure! I'll try to make time to keep iterating on this soon.

@ryannielsen
Copy link

(Since it feels the behavior I've seen is a bug – I'd either expect launching the app in its own security session to be invalid and thus it shouldn't appear as a running app in the user's login session; or that is completely valid and thus com.apple.security.pboxd should not appear as a second, apparently broken instance of the launched app – I filed a bug with Apple. radar://12648274, for those who care and can view.)

@andymatuschak
Copy link
Contributor

Hm, but that means that the XPC service can't have a disjoint set of permissions from its host…

@ClaudiuD
Copy link

ClaudiuD commented Jan 8, 2013

Hello! Thank you for providing a solution for this issue with the Sandbox, but I still can't manage to make my app update with the Sandbox.
I got the test project from https://github.com/ryannielsen/NSDocumentSandboxSparkleTest , but on update it says that "An error occurred in retrieving update information. Please try again later.", have anyone tried this project and works for him? (In this project the Sparkle is missing and I copied from here the Sparkle project, is possible that I don't have the right Sparkle?)
There some new changes from Apple and this solution doesn't work anymore?

What are the steps that should I follow exactly...?

Thank you.

@ryannielsen
Copy link

@andymatuschak I want to say (though I may be mis-remembering) that we tested Sparkle updating with our app being sandboxed and the Sparkle XPCServices being signed but not sandboxed and we were able to successfully upgrade, so that would imply that disjoint permissions are allowed even though the security sessions are different.

@ClaudiuD Did you have a server running which was hosting the appcast? The solution I described earlier is definitely still working. We're using it in our app right now.

@ClaudiuD
Copy link

ClaudiuD commented Jan 8, 2013

Thank you for the response. No, what files should I add to my server?
On my real app, I have the dmg and the xml file on the server, for making the update.

I am happy that your solution works, because I really need to implement it on my app.

@ryannielsen
Copy link

The README.md file in https://github.com/ryannielsen/NSDocumentSandboxSparkleTest describes how to create the test… read the last two paragraphs and the step-by-step instructions at the bottom. In a nutshell, you need

  1. A server that's hosting a valid appcast with a "new" version of the test app
  2. The test app needs to know the hostname and url for the app cast
  3. You need to run an "older" version of the test app that will cause Sparkle to trigger an update

Without those three things, the test will fail.

@ClaudiuD
Copy link

ClaudiuD commented Jan 9, 2013

I implemented this solution to my project too and I respected all the steps, but still that error.
I am using Mac OS 10.7 ... works only for Mac OS 10.8?

@ClaudiuD
Copy link

ClaudiuD commented Jan 9, 2013

So start again.... I take the Sparkle project from this location https://github.com/tumult/Sparkle (is this the right version?) and I copy in the folder Sparkle from your test app. I change the server base url path constantes and current version of project to 2 and build, but not Appcast folder on the desktop.... I am doing something wrong?

@ClaudiuD
Copy link

ClaudiuD commented Jan 9, 2013

Can you please tell me the steps I need to follow for integrating this Sparkle on my project.
Because I did all of this and I see the service on the build for it still doesn't work and I really need to make this update.

I don't know what could be wrong...

@ClaudiuD
Copy link

ClaudiuD commented Jan 9, 2013

On console I get, for my project, not the test project:
1/9/13 5:50:25.630 PM sandboxd: ([26997]) hdiutil(26997) deny sysctl-write
1/9/13 5:50:25.945 PM sandboxd: ([26997]) hdiutil(26997) deny sysctl-write
1/9/13 5:50:26.334 PM sandboxd: ([26999]) hdiutil(26999) deny sysctl-write
1/9/13 5:50:26.354 PM sandboxd: ([26999]) hdiutil(26999) deny sysctl-write
1/9/13 5:50:26.441 PM sandboxd: ([27001]) diskimages-helpe(27001) deny mach-lookup BE03ABED-723B-4772-B435-9B734C05E3A4
1/9/13 5:50:26.442 PM diskimages-helper: ERROR: couldn't connect to framework.
1/9/13 5:50:26.442 PM diskimages-helper: DIHelper: setupConnectionToFrameworkWithUUID: failed

Its clearly that I don't have permissions to write, because of the Sandbox, but how this service starts on non-sandbox....
I respected the steps, but I am not sure if the service starts...

@ryannielsen
Copy link

Hi @ClaudiuD this isn't the proper venue for diagnosing what's going wrong with my example project. I'm also afraid I cannot offer support for the project. I created it to ensure the changes in this pull request would meet our needs for our project, nothing more and nothing less.

A quick google on "diskimages sandbox" returns http://stackoverflow.com/questions/9119191/sandbox-and-nstask, which then led me to search devforums.apple.com. At the bottom of this thread, you'll see what's causing problems: https://devforums.apple.com/message/745710

It seems that sandboxed apps won't be able to use dmgs as their archive and distribution mechanism. The Sparkle changes it tests work for us on our app which is sandboxed on 10.7 and 10.8, but we distribute zip files.

@ClaudiuD
Copy link

ClaudiuD commented Jan 9, 2013

Thank you for you answer. You save me a lot of time and nerves :) . Best.

@ClaudiuD
Copy link

This Sparkle works with zip and in my project too. Great job.
Thank you.

@samdeane
Copy link
Contributor

samdeane commented Feb 8, 2013

@andymatuschak: would it be worth making a branch for this stuff on your repo, if you don't have the time to actually review the changes and merge them into your master branch?

That way people have an obvious place to go to get the latest sandbox-friendly version. At the moment it's a bit confusing - you have to read all the way through this thread to work out which commit to take from where.

I've got a "sandboxing" branch on my fork which I'm going to attempt to use for the latest version of Neu, but I'm a not 100% certain at the moment that I've picked up everything I should :)

@andymatuschak
Copy link
Contributor

On Feb 8, 2013, at 6:59 AM, Sam Deane notifications@github.com wrote:

@andymatuschak: would it be worth making a branch for this stuff on your repo, if you don't have the time to actually review the changes and merge them into your master branch?

Ah, that's not the issue. I have reviewed these changes. I haven't merged them because they amount to intentionally shipping a backdoor for one's App Sandbox. I don't want to encourage people to adopt this approach. See the comment at #165 (comment) for more.

@samdeane
Copy link
Contributor

Ok, that makes sense, and I wasn't meaning to imply that you were slacking ;)

It looks like some additional work has been done since you posted those comments. If we could collectively figure out a list of jobs still to be done to get it to an acceptable state for merging, then that would increase the likelihood of one of us picking up the baton and doing those jobs.

Personally, I'm in a similar position to Erik. I want to sandbox the non-App store version of my app, just for the sake of parity with the App store version, and so that I don't have to maintain two wildly different code-paths.

Of course I'd like it to be secure ultimately, but getting a new version of my app out there is higher priority in the short term. Of course, as long as Sparkle is working, I can update the app as Sparkle's sandboxing support gets improved.

@samdeane
Copy link
Contributor

It seems to me that one of the main vulnerabilities could be eliminated by simply not passing the path of finish_installation to the XPC service. That stops it from being an arbitrary copying tool. Can't the service figure that out for itself (it should be a fixed relative path from the xpc service's own bundle location, as Andy mentioned in an earlier post).

For the other vulnerability, is it enough to have finish_installation verify that the package that it's going to install, the package it's going to replace, and itself were all signed by the same entity? This seems like it ought to be a way to generalise the code so that no information needs to be passed in other than the location of the package to be installed. An exploited app can do whatever it wants with the package or the path to it, but it won't be able to make these signatures match.

What am I missing?

@samdeane
Copy link
Contributor

It seems to me that an even simpler approach would be to launch the finish_installation tool in the downloaded bundle directly. I don't think it would have a problem with copying the application into place (including itself) even though it's running. The only problem it would have would be in deleting the downloaded bundle afterwards, since it would be inside it. However, this step could just as easily be performed by the updated app, the next time it launched.

I'm probably missing something with this idea, but it would eliminate the need for an xpc helper at all.

@samdeane
Copy link
Contributor

FWIW, I also wonder if this might be the point to perform some more radical pruning of the code.

I added an issue: #248

@andymatuschak
Copy link
Contributor

It looks like some additional work has been done since you posted those comments. If we could collectively figure out a list of jobs still to be done to get it to an acceptable state for merging, then that would increase the likelihood of one of us picking up the baton and doing those jobs.

I don't think any of the issues in #165 (comment) have been addressed. The first and last bullet points are the main issues.

It seems to me that an even simpler approach would be to launch the finish_installation tool in the downloaded bundle directly.

You can't launch an app in a way which would inherit the parent's sandbox.

@ghost
Copy link

ghost commented Mar 16, 2013

Is there a fork of Sparkle that supports Sandboxing with CodeSigning right now? I could really use this in my project. I'm distributing a private beta of an app to beta testers and this would be really helpful.

mikeabdullah pushed a commit to karelia/Sparkle that referenced this pull request Nov 27, 2013
mikeabdullah pushed a commit to karelia/Sparkle that referenced this pull request Nov 27, 2013
…merge

Merging in Sam Dean's sandboxing branch which contains the work to get Sparkle to work with sandboxing done by several folks in this pull request thread: sparkle-project#165

Resolved with changes from upstream
@kornelski
Copy link
Member

Because this branch is very old and has security issues (#165 (comment)) — I'm closing this pull request.

I realize that sandboxing support is very important and it's a high priority issue, so I'm starting a discussion in #363 to work out how can we restart this effort with a more secure approach.

@kornelski kornelski closed this Jul 2, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sparkle not compatible with Lion sandbox